﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GestionePolveri2.DAL;
using GestionePolveriLib.BL;
using FrameworkLib.Facades;
using FrameworkLib.Filters;
using LinqKit;
using GestionePolveriLib.BL.FilterBags;

namespace GestionePolveriLib.Facades
{
    [Serializable]
    public class ComposizioneColoreFacadeExt : ComposizioneColoreFacade //FacadeBase<GestionePolveriEntities>
    {
        GestionePolveriEntities context = null;

        public ComposizioneColoreFacadeExt()
        {
            context = this.GetContext();
        }

        public ComposizioneColoreFacadeExt(string connectionString)
        {
            context = this.GetContext(connectionString);
        }

        public new void LoadAsync(BackgroundWorkerCallbackBase.Callback callback)
        {
            this.RunAsync(() => GetAll(), callback);
        }

        public new List<ComposizioneColoreExt> GetAll()
        {
            List<ComposizioneColoreExt> retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          select new ComposizioneColoreExt
                          {
                              ID = x.IDComposizione,
                              Colore = (from y in context.AnagColori
                                        where y.IDColore == x.IDColore
                                        select new Colore
                                        {
                                            ID = y.IDColore,
                                            CodiceColore = y.CodiceColore,
                                            Descrizione = y.Descrizione,
                                            Famiglia = (from f in context.AnagFamiglie
                                                        where f.IDFamiglia == y.IDFamiglia
                                                        select new FamigliaColore
                                                        {
                                                            ID = f.IDFamiglia,
                                                            Descrizione = f.Descrizione
                                                        }).FirstOrDefault()
                                        }).FirstOrDefault(),
                              //Polveri = (from z in context.AnagPolveri
                              //           where z.IDPolvere == x.IDPolvere
                              //           select new PolvereExt
                              //           {
                              //               Descrizione = z.Descrizione
                              //           }),
                              Applicazione = x.Applicazione
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool Add(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                Transact(() => {
                    foreach (PolvereExt p in data.Polveri)
                    {
                        ComposizioneColori imp = new ComposizioneColori();
                        imp.IDColore = data.Colore.ID;
                        imp.IDPolvere = p.ID;
                        imp.Applicazione = string.Format("{0}{1}", (p.Base ? "b" : ""), (p.Venatura ? "v" : ""));

                        context.ComposizioneColori.AddObject(imp);
                        context.SaveChanges();

                        retValue = true;
                    }
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool Add(List<ComposizioneColoreExt> data)
        {
            bool retValue = false;

            Transact(() =>
            {
                foreach (ComposizioneColoreExt cc in data)
                {
                    Add(cc);
                }

                context.SaveChanges();
                retValue = true;
            });

            return retValue;
        }

        public bool Delete(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDComposizione == data.ID
                          select x;

                if (obj.Any())
                {
                    Transact(() =>
                    {
                        context.ComposizioneColori.DeleteObject(obj.FirstOrDefault());

                        context.SaveChanges();
                        retValue = true;
                    });
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool DeleteByColore(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == data.Colore.ID
                          select x;

                if (obj.Any())
                {
                    Transact(() =>
                    {
                        foreach (ComposizioneColori cc in obj.ToList())
                        {
                            context.ComposizioneColori.DeleteObject(cc);
                        }

                        context.SaveChanges();
                        retValue = true;
                    });
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool DeleteByPolvere(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == data.Colore.ID
                          select x;

                if (obj.Any())
                {
                    Transact(() =>
                    {
                        foreach (ComposizioneColori cc in obj.ToList())
                        {
                            context.ComposizioneColori.DeleteObject(cc);
                        }

                        context.SaveChanges();
                        retValue = true;
                    });
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool Modify(ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == data.Colore.ID
                          select new ComposizioneColore() {
                              ID = x.IDComposizione
                          };

                if (obj.Any())
                {
                    Transact(() =>
                    {
                        List<ComposizioneColore> m_composizioni = (List<ComposizioneColore>)obj.ToList();

                        // cancello la formula precedente...
                        foreach (ComposizioneColore cc in m_composizioni)
                        {
                            var objToDelete = from x in context.ComposizioneColori
                                              where x.IDComposizione == cc.ID
                                              select x;

                            if (obj.Any())
                            {
                                context.ComposizioneColori.DeleteObject(objToDelete.FirstOrDefault());
                            }
                        }

                        // inserisco la nuova formula...
                        foreach (PolvereExt p in data.Polveri)
                        {
                            ComposizioneColori imp = new ComposizioneColori();
                            imp.IDColore = data.Colore.ID;
                            imp.IDPolvere = p.ID;
                            imp.Applicazione = string.Format("{0}{1}", (p.Base ? "b" : ""), (p.Venatura ? "v" : ""));

                            context.ComposizioneColori.AddObject(imp);
                        }

                        context.SaveChanges();
                        retValue = true;
                    });
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public ComposizioneColoreExt Get(int id)
        {
            ComposizioneColoreExt retValue = null;

            var obj = from x in context.ComposizioneColori
                      where x.IDComposizione == id
                      select new ComposizioneColoreExt
                      {
                          ID = x.IDComposizione,
                          Colore = (from c in context.AnagColori
                                    where c.IDColore == x.IDColore
                                    select new Colore
                                    {
                                        ID = c.IDColore,
                                        CodiceColore = c.CodiceColore,
                                        Famiglia = (from f in context.AnagFamiglie
                                                    where f.IDFamiglia == c.IDFamiglia
                                                    select new FamigliaColore
                                                    {
                                                        ID = f.IDFamiglia
                                                    }).FirstOrDefault()
                                    }).FirstOrDefault(),
                          Applicazione = x.Applicazione
                      };

            if (obj.Any())
            {
                retValue = obj.FirstOrDefault();
            }

            return retValue;
        }

        public List<ComposizioneColoreExt> GetByColore(int idColore)
        {
            List<ComposizioneColoreExt> retValue = null;

            var obj = from x in context.ComposizioneColori
                      where x.IDColore == idColore
                      select new ComposizioneColoreExt
                      {
                          ID = x.IDComposizione
                      };

            if (obj.Any())
            {
                retValue = obj.ToList();
            }

            return retValue;
        }

        public List<ComposizioneColoreExt> GetByPolvere(int idPolvere)
        {
            List<ComposizioneColoreExt> retValue = null;

            var obj = from x in context.ComposizioneColori
                      where x.IDPolvere == idPolvere
                      select new ComposizioneColoreExt
                      {
                          ID = x.IDComposizione
                      };

            if (obj.Any())
            {
                retValue = obj.ToList();
            }

            return retValue;
        }

        public List<Colore> GetColoriAssociati(int polvereId)
        {
            List<Colore> retValue = null;

            try
            {
                //this.Transact(() => { });

                var obj = (from x in context.ComposizioneColori
                          where x.IDPolvere == polvereId
                          select new Colore
                          {
                              ID = x.AnagColori.IDColore,
                              CodiceColore = x.AnagColori.CodiceColore,
                              Applicazione = x.AnagColori.ComposizioneColori.FirstOrDefault().Applicazione,
                              //Applicazione = (from a in context.ComposizioneColori where a.IDPolvere == polvereId select a.Applicazione).f,
                              Famiglia = (from y in context.AnagFamiglie
                                          where y.IDFamiglia == x.AnagColori.IDFamiglia
                                          select new FamigliaColore
                                          {
                                              ID = y.IDFamiglia,
                                              Descrizione = y.Descrizione
                                          }).FirstOrDefault()
                          });

                if (obj.Any())
                {
                    retValue = obj.ToList();

                    foreach (Colore c in retValue)
                    {
                        var apps = from a in context.ComposizioneColori 
                                   where a.IDColore == c.ID && a.IDPolvere == polvereId
                                   orderby a.Applicazione ascending
                                   select a.Applicazione;

                        string app = string.Empty;
                        foreach (string s in apps)
                        {
                            if (!app.Contains(s))
                            {
                                app += s + ",";
                            }
                        }

                        app = app.Substring(0, app.LastIndexOf(","));
                        c.Applicazione = app;
                    }
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public string GetColoriAssociati2(int polvereId)
        {
            string retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDPolvere == polvereId
                          select new Colore
                          {
                              CodiceColore = x.AnagColori.CodiceColore,
                              Applicazione = x.Applicazione
                          };

                if (obj.Any())
                {
                    foreach (Colore c in obj.ToList())
                    {
                        retValue += string.Format("{0}/{1} ", c.CodiceColore, c.Applicazione);
                    }
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public List<PolvereExt> GetPolveriAssociate(int coloreId)
        {
            List<PolvereExt> retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == coloreId
                          select new PolvereExt
                          {
                              ID = x.AnagPolveri.IDPolvere,
                              CodicePolvere = x.AnagPolveri.CodicePolvere,
                              Base = (x.Applicazione == "b" ? true : (x.Applicazione == "bv" ? true : false)),
                              Venatura = (x.Applicazione == "v" ? true : (x.Applicazione == "bv" ? true : false)),
                              Descrizione = x.AnagPolveri.Descrizione,
                              Note = x.AnagPolveri.Note,
                              FamiglieColori = (from y in context.ComposizioneColori
                                                where y.IDPolvere == x.AnagPolveri.IDPolvere
                                                select y.AnagColori.AnagFamiglie.Descrizione
                                                ).FirstOrDefault(),
                              Fornitore = (from f in context.AnagFornitori
                                           where f.IDFornitore == x.AnagPolveri.IDFornitore
                                           select new Fornitore { ID=f.IDFornitore, Descrizione=f.Descrizione }).FirstOrDefault()
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public string GetApplicazioneColore(int idColore)
        {
            string retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDColore == idColore
                          select x.Applicazione;

                if (obj.Any())
                {
                    foreach (string a in obj)
                    {
                        retValue += a + ",";
                    }

                    retValue = retValue.Substring(0, retValue.LastIndexOf(","));
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public string GetFamiglieColoriAssociate(int polvereId)
        {
            string retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDPolvere == polvereId
                          select x.AnagColori.AnagFamiglie.Descrizione;

                if (obj.Any())
                {
                    retValue = obj.FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool CheckDuplicate(ComposizioneColoreExt data)
        {
            bool retValue = true;

            int m_equals = 0;
            int m_notEquals = 0;

            var obj = from x in context.ComposizioneColori where x.IDColore == data.Colore.ID select x;

            if (obj.Any())
            {
                List<ComposizioneColori> objs = obj.ToList();

                foreach (ComposizioneColori cc in objs)
                {
                    PolvereExt p = (from x in data.Polveri where x.CodicePolvere == cc.AnagPolveri.CodicePolvere select x).FirstOrDefault();

                    if (p != null)
                    {
                        if (p.GetApplicazione() == cc.Applicazione)
                        {
                            m_equals++;
                        }
                        else
                        {
                            m_notEquals++;
                        }
                    }
                }

                if (data.Polveri.Count() == m_equals)
                {
                    retValue = true;
                }
                else if (m_notEquals > 0 && m_equals == 0)
                {
                    retValue = false;
                }
                else
                {
                    retValue = false;
                }
            }
            else 
            {
                retValue = false;
            }

            return retValue;
        }

        public List<ComposizioneColoriSL> GetDatiOnSingleLine()
        {
            List<ComposizioneColoriSL> retValue = null;

            GestionePolveriEntities ctx = new GestionePolveriEntities();
            retValue = ctx.ComposizioneColoriSingleLine().ToList();

            return retValue;
        }

        #region Metodi aggiunti dopo l'introduzione della nuova tabella Formule...
        public List<Formula> GetDatiComposizioneColoreFormule()
        {
            List<Formula> retValue = null;

            GestionePolveriEntities context = this.GetContext();
            var obj = from x in context.Formule
                      join y in context.ComposizioneColori on x.IDFormula equals y.IDFormula
                      orderby y.AnagColori.CodiceColore
                      select new Formula
                      {
                          ID = x.IDFormula,
                          Descrizione = x.Descrizione,
                          ComposizioneFormulaXLoad = (
                                        new ComposizioneColore()
                                        {
                                            ID = y.IDComposizione,
                                            FornitoreDesc = y.AnagPolveri.AnagFornitori.Descrizione,
                                            Colore = (from ac in context.AnagColori
                                                      where ac.IDColore == y.IDColore
                                                      select new Colore
                                                      {
                                                          Applicazione = "",
                                                          ID = ac.IDColore,
                                                          CodiceColore = ac.CodiceColore,
                                                          Descrizione = ac.Descrizione,
                                                          Note = ac.Note,
                                                          Famiglia = (from f in context.AnagFamiglie
                                                                      where f.IDFamiglia == ac.IDFamiglia
                                                                      select new FamigliaColore
                                                                      {
                                                                          ID = f.IDFamiglia,
                                                                          Descrizione = f.Descrizione
                                                                      }).FirstOrDefault()
                                                      }).FirstOrDefault(),
                                            Polvere = (from z in context.AnagPolveri
                                                       where z.IDPolvere == y.IDPolvere
                                                       select new Polvere
                                                       {
                                                           ID = z.IDPolvere,
                                                           CodicePolvere = z.CodicePolvere,
                                                           Descrizione = z.Descrizione,
                                                           Note = z.Note,
                                                           TipologiaSM = new TipologiaScortaMinima() { 
                                                               ID = z.TipologieScortaMinimaPolvere.IDTipologiaScortaMinimaPolvere, 
                                                               Codice=z.TipologieScortaMinimaPolvere.Codice, 
                                                               Descrizione= z.TipologieScortaMinimaPolvere.Descrizione 
                                                           }
                                                       }).FirstOrDefault(),
                                            Applicazione = (y.Applicazione == "b" ? "base" : "vena"),
                                            Ufficiale = y.Ufficiale.Value,
                                            Superata = y.Superata.Value
                                        }
                          ),
                          Ufficiale = x.Ufficiale.Value,
                          Superata = x.Superata.Value
                      };

            if (obj.Any())
            {
                retValue = obj.ToList();
            }

            return retValue;
        }

        public List<Formula> GetDatiComposizioneColoreFormule(FilterBase<Formule> filter)
        {
            List<Formula> retValue = null;

            GestionePolveriEntities context = this.GetContext();

            var obj = from x in context.Formule.AsExpandable().Where(filter.SetUpFilter())
                      join y in context.ComposizioneColori on x.IDFormula equals y.IDFormula
                      orderby y.AnagColori.CodiceColore
                      select new Formula
                      {
                          ID = x.IDFormula,
                          Descrizione = x.Descrizione,
                          ComposizioneFormulaXLoad = (
                                        new ComposizioneColore()
                                        {
                                            ID = y.IDComposizione,
                                            FornitoreDesc = y.AnagPolveri.AnagFornitori.Descrizione,
                                            Colore = (from ac in context.AnagColori
                                                      where ac.IDColore == y.IDColore
                                                      select new Colore
                                                      {
                                                          Applicazione = "",
                                                          ID = ac.IDColore,
                                                          CodiceColore = ac.CodiceColore,
                                                          Descrizione = ac.Descrizione,
                                                          Note = ac.Note,
                                                          Famiglia = (from f in context.AnagFamiglie
                                                                      where f.IDFamiglia == ac.IDFamiglia
                                                                      select new FamigliaColore
                                                                      {
                                                                          ID = f.IDFamiglia,
                                                                          Descrizione = f.Descrizione
                                                                      }).FirstOrDefault(),
                                                          PianoColore = new PianoColore() { IsDiSerie=(ac.IsDiSerie.HasValue ? ac.IsDiSerie.Value : false), Fascia=ac.Fascia, TempiConsegna =ac.TempiConsegna }
                                                      }).FirstOrDefault(),
                                            Polvere = (from z in context.AnagPolveri
                                                       where z.IDPolvere == y.IDPolvere
                                                       select new Polvere
                                                       {
                                                           ID = z.IDPolvere,
                                                           CodicePolvere = z.CodicePolvere,
                                                           Descrizione = z.Descrizione,
                                                           Note = z.Note,
                                                           Applicazione = (y.Applicazione == "b" ? "base" : "vena"),
                                                           IsCodiceCustom = z.IsCodiceCustom,
                                                           TipologiaSM = new TipologiaScortaMinima()
                                                           {
                                                               ID = z.TipologieScortaMinimaPolvere.IDTipologiaScortaMinimaPolvere,
                                                               Codice = z.TipologieScortaMinimaPolvere.Codice,
                                                               Descrizione = z.TipologieScortaMinimaPolvere.Descrizione
                                                           }
                                                       }).FirstOrDefault(),
                                            Applicazione = (y.Applicazione == "b" ? "base" : "vena"),
                                            Ufficiale = (y.Ufficiale.HasValue ? y.Ufficiale.Value : false),
                                            Superata = (y.Superata.HasValue ? y.Superata.Value : false),
                                            PrezzoUnitarioPolvere = (y.AnagPolveri.Lotti.Where(k => k.IDPolvere == y.IDPolvere).OrderByDescending(p => p.DataDdt).Take(1).FirstOrDefault().PrezzoUnitario)
                                        }
                          ),
                          Ufficiale = (x.Ufficiale.HasValue ? x.Ufficiale.Value : false),
                          Superata = (x.Superata.HasValue ? x.Superata.Value : false),
                          DataCreazione = (x.DataCreazione.HasValue ? x.DataCreazione.Value : DateTime.MinValue)
                      };

            if (obj.Any())
            {
                retValue = obj.ToList();
              
                // quando impostato il filtro per Applicazione, devo eliminare i dettagli che non corrispondo al tipo applicazione indicato...
                if (!string.IsNullOrWhiteSpace(((GestionePolveriLib.BL.FilterBags.FormulaFilterBag)filter).Applicazione))
                {
                    retValue.RemoveAll(x => x.ComposizioneFormulaXLoad.Applicazione != (((GestionePolveriLib.BL.FilterBags.FormulaFilterBag)filter).Applicazione == "b" ? "base" : "vena"));
                }

                // quando impostato il filtro per Tipo, devo eliminare i dettagli che non corrispondo al tipo indicato...
                switch (((GestionePolveriLib.BL.FilterBags.FormulaFilterBag)filter).Tipo)
                {
                    case PolvereTypes.Tutte:
                        break;
                    case PolvereTypes.Normali:
                        retValue.RemoveAll(x => x.ComposizioneFormulaXLoad.Polvere.IsCodiceCustom == true);
                        break;
                    case PolvereTypes.XXXX:
                        retValue.RemoveAll(x => x.ComposizioneFormulaXLoad.Polvere.IsCodiceCustom == false);
                        break;
                    default:
                        break;
                }

                if (!string.IsNullOrWhiteSpace(((GestionePolveriLib.BL.FilterBags.FormulaFilterBag)filter).CodicePolvere))
                {
                    retValue.RemoveAll(x => x.ComposizioneFormulaXLoad.Polvere.CodicePolvere != ((GestionePolveriLib.BL.FilterBags.FormulaFilterBag)filter).CodicePolvere);
                }

                if (!string.IsNullOrWhiteSpace(((GestionePolveriLib.BL.FilterBags.FormulaFilterBag)filter).Fornitore))
                {
                    retValue.RemoveAll(x => (x .ComposizioneFormulaXLoad.FornitoreDesc != ((GestionePolveriLib.BL.FilterBags.FormulaFilterBag)filter).Fornitore));
                }
            }

            return retValue;
        }

        public List<ComposizioneColore> GetDatiComposizioneColore()
        {
            List<ComposizioneColore> retValue = null;

            GestionePolveriEntities context = this.GetContext();
            var obj = from x in context.ComposizioneColori
                      join y in context.Formule on x.IDFormula equals y.IDFormula
                      select new ComposizioneColore
                      {
                          ID = x.IDComposizione,
                          Colore = (from ac in context.AnagColori
                                    where ac.IDColore == x.IDColore
                                    select new Colore
                                    {
                                        Applicazione = "",
                                        ID = ac.IDColore,
                                        CodiceColore = ac.CodiceColore,
                                        Descrizione = ac.Descrizione,
                                        Note = ac.Note,
                                        Famiglia = (from f in context.AnagFamiglie
                                                    where f.IDFamiglia == ac.IDFamiglia
                                                    select new FamigliaColore
                                                    {
                                                        ID = f.IDFamiglia,
                                                        Descrizione = f.Descrizione
                                                    }).FirstOrDefault()
                                    }).FirstOrDefault(),
                          Polvere = (from z in context.AnagPolveri
                                     where z.IDPolvere == x.IDPolvere
                                     select new Polvere
                                     {
                                         ID = z.IDPolvere,
                                         CodicePolvere = z.CodicePolvere,
                                         Descrizione = z.Descrizione,
                                         Note = z.Note
                                     }).FirstOrDefault(),
                          FornitoreDesc = x.AnagPolveri.AnagFornitori.Descrizione,
                          Applicazione = (x.Applicazione == "b" ? "base" : "vena"),
                          Ufficiale = y.Ufficiale.Value,
                          Superata = y.Superata.Value
                      };

            if (obj.Any())
            {
                retValue = obj.ToList();
            }

            return retValue;
        }

        public List<ComposizioneColore> GetDatiComposizioneColore(FilterBase<ComposizioneColori> filter)
        {
            List<ComposizioneColore> retValue = null;

            GestionePolveriEntities context = this.GetContext();
            var obj = from x in context.ComposizioneColori.AsExpandable().Where(filter.SetUpFilter())
                      join y in context.Formule on x.IDFormula equals y.IDFormula
                      select new ComposizioneColore
                      {
                          ID = x.IDComposizione,
                          Colore = (from ac in context.AnagColori
                                    where ac.IDColore == x.IDColore
                                    select new Colore
                                    {
                                        Applicazione = "",
                                        ID = ac.IDColore,
                                        CodiceColore = ac.CodiceColore,
                                        Descrizione = ac.Descrizione,
                                        Note = ac.Note,
                                        Famiglia = (from f in context.AnagFamiglie
                                                    where f.IDFamiglia == ac.IDFamiglia
                                                    select new FamigliaColore
                                                    {
                                                        ID = f.IDFamiglia,
                                                        Descrizione = f.Descrizione
                                                    }).FirstOrDefault()
                                    }).FirstOrDefault(),
                          Polvere = (from z in context.AnagPolveri
                                     where z.IDPolvere == x.IDPolvere
                                     select new Polvere
                                     {
                                         ID = z.IDPolvere,
                                         CodicePolvere = z.CodicePolvere,
                                         Descrizione = z.Descrizione,
                                         Note = z.Note
                                     }).FirstOrDefault(),
                          FornitoreDesc = x.AnagPolveri.AnagFornitori.Descrizione,
                          Applicazione = (x.Applicazione == "b" ? "base" : "vena"),
                          Ufficiale = y.Ufficiale.Value,
                          Superata = y.Superata.Value
                      };

            if (obj.Any())
            {
                retValue = obj.ToList();
            }

            return retValue;
        }

        public bool AddFormula(Formula formula)
        {
            bool retValue = false;

            try
            {
                Transact(() =>
                {
                    Formule f = new Formule();
                    f.Descrizione = formula.Descrizione;
                    f.Ufficiale = formula.Ufficiale;
                    f.Superata = formula.Superata;
                    f.DataCreazione = formula.DataCreazione;

                    context.Formule.AddObject(f);

                    AddComposizioneFormula(f, formula.ComposizioneFormulaXInsert);

                }, context);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool AddComposizioneFormula(Formule formula, ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                //System.Data.Objects.DataClasses.EntityCollection<ComposizioneColori> c = new System.Data.Objects.DataClasses.EntityCollection<ComposizioneColori>();

                foreach (PolvereExt p in data.Polveri)
                {
                    ComposizioneColori imp = new ComposizioneColori();
                    imp.IDColore = data.Colore.ID;
                    imp.IDPolvere = p.ID;
                    imp.Applicazione = string.Format("{0}{1}", (p.Base ? "b" : ""), (p.Venatura ? "v" : ""));
                    imp.Ufficiale = p.Ufficiale;
                    imp.Superata = p.Superata;

                    formula.ComposizioneColori.Add(imp);

                    // aggiornamento FamigliaColoriXPolveri...
                    AddToFamigliaColoriXPolveri(p.ID, data.Colore, imp.Applicazione);

                    retValue = true;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        private void AddToFamigliaColoriXPolveri(int polvereID, Colore colore, string applicazione)
        {
            // aggiungo alla FamigliaColoriXPolveri...
            GestionePolveriLib.BL.FamiglieColoriXPolveri fcxp = null;
            FamiglieColoriXPolveriFacade fcxpf = new FamiglieColoriXPolveriFacade();
            fcxp = fcxpf.Get(polvereID);
            if (fcxp == null)
            {
                fcxp = new GestionePolveriLib.BL.FamiglieColoriXPolveri();

                fcxp.IDPolvere = polvereID;
                fcxp.Applicazione = applicazione;
                fcxp.Famiglie = colore.Famiglia.ID.ToString();

                fcxpf.Add(fcxp);
            }
            else
            {
                if (!fcxp.Applicazione.Contains(applicazione))
                {
                    fcxp.Applicazione += "," + applicazione;
                }

                if (!fcxp.Famiglie.Contains(colore.Famiglia.ID.ToString()))
                {
                    fcxp.Famiglie += "," + colore.Famiglia.ID.ToString();
                }

                fcxp.Applicazione = String.Concat(fcxp.Applicazione.OrderBy(c => c));
                fcxp.Famiglie = String.Concat(fcxp.Famiglie.OrderBy(c => c));

                fcxpf.Modify(fcxp);
            }
        }

        public bool AddComposizioneFormula2(Formule formula, ComposizioneColoreExt data)
        {
            bool retValue = false;

            try
            {
                //System.Data.Objects.DataClasses.EntityCollection<ComposizioneColori> c = new System.Data.Objects.DataClasses.EntityCollection<ComposizioneColori>();

                foreach (PolvereExt p in data.Polveri)
                {
                    ComposizioneColori imp = new ComposizioneColori();
                    imp.IDColore = data.Colore.ID;
                    imp.IDPolvere = p.ID;
                    imp.Applicazione = string.Format("{0}{1}", (p.Base ? "b" : ""), (p.Venatura ? "v" : ""));
                    imp.Ufficiale = p.Ufficiale;
                    imp.Superata = p.Superata;

                    formula.ComposizioneColori.Add(imp);

                    retValue = true;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool ModifyFormula(Formula formula)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.Formule
                          where x.IDFormula == formula.ID
                          select new Formula()
                          {
                              ID = x.IDFormula,
                              Superata = x.Superata.Value,
                              Ufficiale = x.Ufficiale.Value
                          };

                if (obj.Any())
                {
                    Transact(() =>
                    {
                        DeleteFormula(formula);

                        //var objCCToDelete = from x in context.ComposizioneColori
                        //                    where x.IDFormula == obj.FirstOrDefault().ID
                        //                    select x;

                        //if (objCCToDelete.Any())
                        //{
                        //    // cancello i dettagli della formula...
                        //    foreach (ComposizioneColori cc in objCCToDelete.ToList())
                        //    {
                        //        context.ComposizioneColori.DeleteObject(cc);
                        //    }
                        //}

                        //Formule objF = (from x in context.Formule
                        //                  where x.IDFormula == formula.ID
                        //                  select x).FirstOrDefault();

                        Formule objF = new Formule();
                        objF.Descrizione = formula.Descrizione;
                        objF.Ufficiale = formula.Ufficiale;
                        objF.Superata = formula.Superata;
                        objF.DataCreazione = formula.DataCreazione;

                        context.Formule.AddObject(objF);

                        AddComposizioneFormula(objF, formula.ComposizioneFormulaXInsert);

                        retValue = true;

                    }, context);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        //public bool ModifyFormula2(Formula formula)
        //{
        //    bool retValue = false;

        //    try
        //    {
        //        var obj = from x in context.Formule
        //                  where x.IDFormula == formula.ID
        //                  select new Formula()
        //                  {
        //                      ID = x.IDFormula,
        //                      Superata = x.Superata.Value,
        //                      Ufficiale = x.Ufficiale.Value
        //                  };

        //        if (obj.Any())
        //        {
        //            Transact(() =>
        //            {
        //                var objCCToDelete = from x in context.ComposizioneColori
        //                                    where x.IDFormula == obj.FirstOrDefault().ID
        //                                    select x;

        //                if (objCCToDelete.Any())
        //                {
        //                    // cancello i dettagli della formula...
        //                    foreach (ComposizioneColori cc in objCCToDelete.ToList())
        //                    {
        //                        context.ComposizioneColori.DeleteObject(cc);
        //                    }
        //                }

        //                Formule objF = (from x in context.Formule
        //                                where x.IDFormula == formula.ID
        //                                select x).FirstOrDefault();

        //                AddComposizioneFormula2(objF, formula.ComposizioneFormulaXInsert);

        //                objF.Descrizione = formula.Descrizione;
        //                objF.Ufficiale = formula.Ufficiale;
        //                objF.Superata = formula.Superata;

        //                retValue = true;

        //            }, context);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        // throw ex;
        //    }

        //    return retValue;
        //}

        public List<PolvereExt> GetPolveriFormula(long idFormula)
        {
            List<PolvereExt> retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDFormula == idFormula
                          select new PolvereExt
                          {
                              ID = x.AnagPolveri.IDPolvere,
                              CodicePolvere = x.AnagPolveri.CodicePolvere,
                              Base = (x.Applicazione == "b" ? true : (x.Applicazione == "bv" ? true : false)),
                              Venatura = (x.Applicazione == "v" ? true : (x.Applicazione == "bv" ? true : false)),
                              Descrizione = x.AnagPolveri.Descrizione,
                              Note = x.AnagPolveri.Note,
                              Ufficiale = (x.Ufficiale.HasValue ? x.Ufficiale.Value : false),
                              Superata = (x.Superata.HasValue ? x.Superata.Value : false),
                              FamiglieColori = (from y in context.ComposizioneColori
                                                where y.IDPolvere == x.AnagPolveri.IDPolvere
                                                select y.AnagColori.AnagFamiglie.Descrizione
                                                ).FirstOrDefault(),
                              Fornitore = (from f in context.AnagFornitori
                                           where f.IDFornitore == x.AnagPolveri.IDFornitore
                                           select new Fornitore { ID = f.IDFornitore, Descrizione = f.Descrizione }).FirstOrDefault()
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool DeleteFamigliaColoreXPolvere(int IDPolvere, int IDColore)
        {
            bool retValue = false;

            try
            {
                ColoriFacade cf = new ColoriFacade();
                Colore m_colore = cf.Get(IDColore);
                string m_idFamigliaColore = m_colore.Famiglia.ID.ToString();

                var obj = from x in context.FamiglieColoriXPolveri
                          where x.IDPolvere == IDPolvere && x.Famiglie.Contains(m_idFamigliaColore)
                          select x;

                if (obj.Any())
                {
                    GestionePolveri2.DAL.FamiglieColoriXPolveri fcxp = obj.FirstOrDefault();
                    string[] m_famiglie = fcxp.Famiglie.Split(new string[] {","}, StringSplitOptions.RemoveEmptyEntries);
                    if (m_famiglie.Length > 1)
                    {
                        string m_f = string.Empty;
                        foreach (string f in m_famiglie)
                        {
                            if (f == m_idFamigliaColore)
                            {
                                continue;
                            }
                            else
                            {
                                m_f += f + ",";
                            }

                            if (m_f[m_f.Length - 1] == ',')
                            {
                                m_f = m_f.Substring(0, m_f.Length - 1);
                            }
                        }

                        fcxp.Famiglie = m_f;
                        context.SaveChanges();
                    }
                    else
                    {
                        context.FamiglieColoriXPolveri.DeleteObject(obj.FirstOrDefault());
                    }

                    retValue = true;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool DeleteDettaglioFormula(Formula formula)
        {
            bool retValue = false;

            try
            {
                Transact(() =>
                {
                    var objCCToDelete = from x in context.ComposizioneColori
                                        where x.IDFormula == formula.ID
                                        select x;

                    if (objCCToDelete.Any())
                    {
                        // cancello i dettagli della formula...
                        foreach (ComposizioneColori cc in objCCToDelete.ToList())
                        {
                            DeleteFamigliaColoreXPolvere(cc.IDPolvere, cc.IDColore);

                            context.ComposizioneColori.DeleteObject(cc);
                        }
                    }

                    retValue = true;
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public bool DeleteFormula(Formula formula)
        {
            bool retValue = false;

            try
            {
                var obj = from x in context.Formule
                          where x.IDFormula == formula.ID
                          select x;

                if (obj.Any())
                {
                    Transact(() =>
                    {                       
                        DeleteDettaglioFormula(formula);

                        context.Formule.DeleteObject(obj.FirstOrDefault());

                        retValue = true;

                    }, context);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public Formula GetFormula(int coloreID, int polvereId)
        {
            Formula retValue = null;

            try
            {
                var obj = from x in context.Formule
                          join y in context.ComposizioneColori on x.IDFormula equals y.IDFormula
                          where y.IDColore == coloreID && y.IDPolvere == polvereId
                          select new Formula()
                          {
                              ID = x.IDFormula,
                              Superata = x.Superata.Value,
                              Ufficiale = x.Ufficiale.Value
                          };

                if (obj.Any())
                {
                    retValue = obj.FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }

        public List<ComposizioneColore> GetDettagliFormuleOrfani()
        {
            List<ComposizioneColore> retValue = null;

            try
            {
                var obj = from x in context.ComposizioneColori
                          where x.IDFormula == null
                          select new ComposizioneColore
                          {
                              ID = x.IDComposizione,
                              Colore = (from ac in context.AnagColori
                                        where ac.IDColore == x.IDColore
                                        select new Colore
                                        {
                                            Applicazione = "",
                                            ID = ac.IDColore,
                                            CodiceColore = ac.CodiceColore,
                                            Descrizione = ac.Descrizione,
                                            Note = ac.Note,
                                            Famiglia = (from f in context.AnagFamiglie
                                                        where f.IDFamiglia == ac.IDFamiglia
                                                        select new FamigliaColore
                                                        {
                                                            ID = f.IDFamiglia,
                                                            Descrizione = f.Descrizione
                                                        }).FirstOrDefault()
                                        }).FirstOrDefault(),
                              Polvere = (from z in context.AnagPolveri
                                         where z.IDPolvere == x.IDPolvere
                                         select new Polvere
                                         {
                                             ID = z.IDPolvere,
                                             CodicePolvere = z.CodicePolvere,
                                             Descrizione = z.Descrizione,
                                             Note = z.Note
                                         }).FirstOrDefault(),
                              FornitoreDesc = x.AnagPolveri.AnagFornitori.Descrizione,
                              Applicazione = (x.Applicazione == "b" ? "base" : "vena")
                          };

                if (obj.Any())
                {
                    retValue = obj.ToList();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return retValue;
        }
        #endregion
    }
}
